package com.example.gesture.Swipeable

import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.size
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp

//定义枚举状态
enum class Status {
    CLOSE, OPEN
}

//使用 swipeable 修饰符至少需要传入三个参数 swipeableState 、 anchors 、 orientation
//swipeableState：通过 swipeableState 的设置可以获取到当前手势的偏移量信息
//anchors：锚点，可以通过锚点设置在不同状态时所应该对应的偏移量信息
//orientation：手势方向，被修饰组件的手势方向只能是水平或垂直
//thresholds (常用非必需)：常用作定制不同锚点间吸附效果的临界阈值，常用有 FixedThreshold(Dp) 和FractionalThreshold(Float)等
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun SwipeableDemo() {
    var blockSize = 48.dp
    //将Dp转化为像素
    var blockSizePx = with(LocalDensity.current) { blockSize.toPx() }
    //通过 rememberSwipeableState 方法获取 SwipeableState 实例，并将初始状态设置为 Status.CLOSE。
    var swipeableState = rememberSwipeableState(initialValue = Status.CLOSE)
    //每个状态都相对应一个锚点，声明每个锚点所对应数值，锚点以键值对进行表示。
    //于此同时，Compose 也得知了开发者所希望的初始状态数值。
    var anchors = mapOf(
        0f to Status.CLOSE,
        blockSizePx to Status.OPEN
    )
    Box(
        modifier = Modifier
            .size(height = blockSize, width = blockSize * 2)
            .background(Color.LightGray)
    ) {
        Box(
            modifier = Modifier
                .offset { IntOffset(swipeableState.offset.value.toInt(), 0) }
                .swipeable(
                    state = swipeableState,
                    orientation = Orientation.Horizontal,
                    anchors = anchors,
                    //从关闭状态到开启状态，滑块仅需移动超过 30% 则会自动吸附到开启状态，从开启状态到关闭状态，滑块需移动超过 50% 才会自动吸附到关闭状态。
                    thresholds = { from, to ->
                        if (from == Status.CLOSE) {
                            FractionalThreshold(0.3f)
                        } else {
                            FractionalThreshold(0.5f)
                        }
                    }
                )
                .size(blockSize)
                .background(Color.DarkGray)
        )
    }
}